package lion.blog.tag;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.jstl.core.LoopTagSupport;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;

import lion.blog.model.BlogArticle;
import lion.blog.model.BlogCatelog;
import lion.blog.service.BlogService;
import lion.blog.util.BlogUtil;
import lion.dev.lang.MapJ;
import lion.dev.web.paging.PagedVo;
import lion.framework.core.bean.BeanFactory;
import lion.framework.core.db.DB;
import lion.framework.core.db.DataTable;
import lion.framework.core.db.SessionFactory;
import lion.framework.core.db.paging.SQLPagingFactory;
import lombok.Setter;

/**
 * 文章列表标签
 * <p>
 * 默认取最新的 <br/>
 * top-comments 评论最多的 random 随机的 <br/>
 * 其他 查询扩展属性 如top hot image
 * 
 * </p>
 * 
 * @author lion
 * @email hl_0074@sina.com
 * @date 2015年8月28日
 */
public class ArticleListTag extends LoopTagSupport {

	private static final long serialVersionUID = 5649077650414528740L;

	@Setter
	private String catelog;
	@Setter
	private int size = 10;
	@Setter
	private String type;

	private Iterator<MapJ> items;

	@Override
	protected boolean hasNext() throws JspTagException {

		return items.hasNext();
	}

	@Override
	protected Object next() throws JspTagException {

		return items.next();
	}

	@Override
	protected void prepare() throws JspTagException {

		PagedVo<MapJ> pagedVo = new PagedVo<>();
		pagedVo.getPaging().setPageNumber(1);
		pagedVo.getPaging().setPageSize(size);

		int catelogId = -1;

		BlogService service = BeanFactory.getBeanFactory(BeanFactory.PLATFORM_BEAN_FACTORY).get("blog.BlogService");

		if (StringUtils.isNotBlank(this.catelog)) {
			BlogCatelog blogCatelog = service.getBlogCatelog(this.catelog);
			if (blogCatelog != null) {
				catelogId = blogCatelog.getId();
			}
		}

		List<BlogArticle> articles = null;

		if (StringUtils.isBlank(type)) {
			articles = getNewestArticles(catelogId);
		} else if (StringUtils.equalsIgnoreCase("top-comments", type)) {
			articles = getTopCommentArticles(catelogId);
		} else if (StringUtils.equalsIgnoreCase("random", type)) {
			articles = getRandomArticles(catelogId);
		} else {
			articles = getPropArticles(type, catelogId);
		}

		List<MapJ> list = new ArrayList<>();
		for (BlogArticle article : articles) {
			MapJ map = article.valueMap();
			map.put("url", BlogUtil.getBlogLink(map, catelog));
			map.put("catelog", service.getBlogCatelog(article.getCatelog()));
			list.add(map);
		}

		this.items = list.iterator();

	}

	/**
	 * 获取随机文章
	 */
	private List<BlogArticle> getRandomArticles(int catelogId) {

		StringBuilder builder = new StringBuilder();
		MapJ param = new MapJ();
		if (catelogId > 0) {
			builder.append(" where catelog=:catelog");
			param.put("catelog", catelog);
		}
		builder.append("order by rand()");
		return BlogArticle.list(0, size, builder.toString(), param, SessionFactory.getCurrentDB());
	}

	/**
	 * 按属性来取文章
	 */
	private List<BlogArticle> getPropArticles(String type, int catelogId) {

		MapJ param = new MapJ();
		param.put("type", "%" + StringEscapeUtils.escapeSql(type) + "%");
		StringBuilder sqlbuilder = new StringBuilder();
		sqlbuilder.append("select * from BlogArticle ba,ModelProp mp where mp.model=ba.id and mp.value like :type");
		if (catelogId > 0) {
			sqlbuilder.append(" and ba.catelog=:catelogId");
			param.put("catelogId", catelogId);
		}

		DB db = SessionFactory.getCurrentDB();
		DataTable dTable = db.query(SQLPagingFactory.paging(db.getType(), sqlbuilder.toString(), 0, size), param);

		return dTable.list(BlogArticle.class);
	}

	/**
	 * 按评论数最多 TODO 优化
	 */
	private List<BlogArticle> getTopCommentArticles(int catelogId) {

		StringBuilder builder = new StringBuilder("select bc.article ,count(*) num from BlogComment bc ");
		MapJ param = new MapJ();
		param.put("catelogId", catelogId);
		if (catelogId > 0) {
			builder.append(" where exists (select 1 from BlogArticle ba where ba.catelog=:catelogId and bc.article = ba.id)");
		}
		builder.append(" group by  article order by num desc");
		DB db = SessionFactory.getCurrentDB();
		MapJ mapJ = db.queryColMap(SQLPagingFactory.paging(db.getType(), builder.toString(), 0, size), "article", "num", param);

		List<BlogArticle> articles = new ArrayList<>();
		for (String key : mapJ.keySet()) {
			articles.add(BlogArticle.load(lion.dev.web.Validator.toInt(key, -1)));
		}
		return articles;
	}

	/**
	 * 获取最新发表的文章 <b>默认</b>
	 */
	private List<BlogArticle> getNewestArticles(int catelogId) {

		StringBuilder builder = new StringBuilder();
		MapJ param = new MapJ();
		if (catelogId > 0) {
			builder.append(" where catelog=:catelog");
			param.put("catelog", catelog);
		}
		builder.append("order by publishTime desc");
		return BlogArticle.list(0, size, builder.toString(), param, SessionFactory.getCurrentDB());
	}

}
